import { _decorator, Component, Node, EventTouch, Vec3, UITransform } from 'cc';
const { ccclass, property } = _decorator;

/**
 * 2D UI 拖拽组件
 * 通过触摸事件实现节点的拖拽功能
 */
@ccclass('DragComponent')
export class DragComponent extends Component {

    @property({ type: Node, displayName: "拖拽主体", tooltip: "指定要拖拽的节点，如果为空则使用当前节点" })
    public dragRoot: Node | null = null;

    @property({ displayName: "是否启用拖拽", tooltip: "是否启用拖拽功能" })
    public enableDrag: boolean = true;

    @property({ displayName: "拖拽时是否置顶", tooltip: "拖拽时是否将节点移到最前面显示" })
    public bringToFront: boolean = true;

    @property({ displayName: "拖拽边界检测", tooltip: "是否启用拖拽边界检测，防止拖出屏幕" })
    public boundaryCheck: boolean = false;

    // 私有变量
    private _isDragging: boolean = false;
    private _dragTarget: Node | null = null;
    private _touchStartPos: Vec3 = new Vec3();
    private _nodeStartPos: Vec3 = new Vec3();
    private _originalSiblingIndex: number = -1;

    public onStart: Function = null;
    public onMove: Function = null;
    public onEnd: Function = null;

    protected onLoad() {
        // 确定拖拽目标
        this._dragTarget = this.dragRoot || this.node;
        
        // 注册触摸事件
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    protected onDestroy() {
        // 取消事件注册
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    /**
     * 触摸开始事件处理
     */
    private onTouchStart(event: EventTouch) {
        if (!this.enableDrag || !this._dragTarget) {
            return;
        }

        this._isDragging = true;
        
        // 记录触摸起始位置
        this._touchStartPos.set(event.getUILocation().x, event.getUILocation().y, 0);
        
        // 记录节点起始位置
        this._nodeStartPos.set(this._dragTarget.position);
        
        // 如果启用置顶，记录原始层级并置顶
        if (this.bringToFront && this._dragTarget.parent) {
            this._originalSiblingIndex = this._dragTarget.getSiblingIndex();
            this._dragTarget.setSiblingIndex(-1); // 移动到最后（最前面显示）
        }

        this.onStart && this.onStart(this._dragTarget);
    }

    /**
     * 触摸移动事件处理
     */
    private onTouchMove(event: EventTouch) {
        if (!this._isDragging || !this.enableDrag || !this._dragTarget) {
            return;
        }

        // 计算偏移量
        const currentTouchPos = event.getUILocation();
        const deltaX = currentTouchPos.x - this._touchStartPos.x;
        const deltaY = currentTouchPos.y - this._touchStartPos.y;

        // 计算新位置
        const newPos = new Vec3(
            this._nodeStartPos.x + deltaX,
            this._nodeStartPos.y + deltaY,
            this._nodeStartPos.z
        );

        // 边界检测
        if (this.boundaryCheck) {
            newPos.set(this.getBoundedPosition(newPos));
        }

        // 设置新位置
        this._dragTarget.setPosition(newPos);

        this.onMove && this.onMove(this._dragTarget, newPos);
    }

    /**
     * 触摸结束事件处理
     */
    private onTouchEnd(event: EventTouch) {
        if (!this._isDragging) {
            return;
        }

        this._isDragging = false;

        // 恢复原始层级
        if (this.bringToFront && this._dragTarget && this._dragTarget.parent && this._originalSiblingIndex !== -1) {
            this._dragTarget.setSiblingIndex(this._originalSiblingIndex);
            this._originalSiblingIndex = -1;
        }

        this.onEnd && this.onEnd(this._dragTarget);
    }

    /**
     * 获取边界限制后的位置
     */
    private getBoundedPosition(targetPos: Vec3): Vec3 {
        if (!this._dragTarget || !this._dragTarget.parent) {
            return targetPos;
        }

        const parentTransform = this._dragTarget.parent.getComponent(UITransform);
        const nodeTransform = this._dragTarget.getComponent(UITransform);
        
        if (!parentTransform || !nodeTransform) {
            return targetPos;
        }

        // 获取父节点和当前节点的尺寸
        const parentSize = parentTransform.contentSize;
        const nodeSize = nodeTransform.contentSize;
        const anchorPoint = nodeTransform.anchorPoint;

        // 计算边界
        const minX = -parentSize.width * 0.5 + nodeSize.width * anchorPoint.x;
        const maxX = parentSize.width * 0.5 - nodeSize.width * (1 - anchorPoint.x);
        const minY = -parentSize.height * 0.5 + nodeSize.height * anchorPoint.y;
        const maxY = parentSize.height * 0.5 - nodeSize.height * (1 - anchorPoint.y);

        // 限制位置
        const boundedPos = new Vec3(targetPos);
        boundedPos.x = Math.max(minX, Math.min(maxX, targetPos.x));
        boundedPos.y = Math.max(minY, Math.min(maxY, targetPos.y));

        return boundedPos;
    }

    /**
     * 设置拖拽启用状态
     */
    public setDragEnabled(enabled: boolean) {
        this.enableDrag = enabled;
        if (!enabled && this._isDragging) {
            // 如果正在拖拽中，强制结束拖拽
            this.onTouchEnd(null as any);
        }
    }

    /**
     * 获取当前是否正在拖拽
     */
    public get isDragging(): boolean {
        return this._isDragging;
    }

    /**
     * 获取拖拽目标节点
     */
    public get dragTarget(): Node | null {
        return this._dragTarget;
    }

    /**
     * 设置拖拽目标节点
     */
    public setDragTarget(target: Node | null) {
        this.dragRoot = target;
        this._dragTarget = target || this.node;
    }
}
